
Imports System.Threading
Imports storoomc
Imports storcore

Public Module stornode
    Public Const defaultConfigfile As String = "stornode.ini"
    Friend WithEvents config As configMonitor = Nothing
    Private configfile As String = defaultConfigfile
    Friend slicemgr As storageInterface = Nothing
    Private slices As storoomOper = Nothing
    Private memslices As memslices = Nothing
    Private server As nodeserver = Nothing
    Private restart As Boolean = False

    Public Function datapath() As String
        Static rtn As String = config.parameter(configNaming.stornode.name, _
                                                configNaming.stornode.datapath, _
                                                configNaming.stornode.defaultValue.datapath)
        Return rtn
    End Function

    Public Function busy() As Boolean
        Return (Not slices Is Nothing) AndAlso (slices.jobcount() > 0)
    End Function

    Private Sub startService()
        If config Is Nothing Then
            config = New configMonitor()
            If Not config.open(configfile) Then
                raiseError("failed to open configfile " + configfile + ", start shutdown" _
                            , errorHandle.errorType.exclamation)
                shutdown()
            Else
                If Not memslices Is Nothing Then
                    memslices.close()
                End If
                If Not slices Is Nothing Then
                    slices.close()
                End If
                Dim slicesType As String = Nothing
                slicesType = config.parameter(configNaming.stornode.name, _
                                              configNaming.stornode.slicesType, _
                                              configNaming.stornode.defaultValue.slicesType)
                If strsame(slicesType, "memslices", False) Then
                    memslices = New memslices()
                    slicemgr = memslices
                    memslices.start()
                Else
                    singleThreadTM.register()
                    If strsame(slicesType, "slices_hash", False) Then
                        slices = New slices_hash()
                    Else
                        slices = New slices()
                    End If
                    slicemgr = slices
                    slices.start()
                End If
                raiseError("slicesType ", slicemgr.GetType().FullName())
                If server Is Nothing Then
                    server = New nodeserver()
                End If
                server.start()
            End If
        End If
    End Sub

    Private Sub shutdownService()
        If Not server Is Nothing Then
            server.stop()
            server = Nothing
        End If
        If Not slicemgr Is Nothing Then
            slicemgr.close()
            slicemgr = Nothing
        End If
    End Sub

    Private Sub shutdown()
        shutdownService()
        finishmain()
    End Sub

    Private Sub monitor()
        If Not slicemgr Is Nothing AndAlso Not server Is Nothing Then
            registerConsoleExtHandle()

restart:
            While Not consoleExtSignal()
                If restart OrElse (slicemgr.health() AndAlso server.health()) Then
                    sleep(1000)
                Else
                    Exit While
                End If
            End While

            If Not consoleExtSignal() Then
                If Not slicemgr.health() Then
                    raiseError("slices engender an error, start shutdown.", errorHandle.errorType.exclamation)
                ElseIf Not server.health() Then
                    raiseError("server engender an error, start shutdown.", errorHandle.errorType.exclamation)
                Else
                    raiseError("temporary slices or server error, return to monitor.", _
                               errorHandle.errorType.exclamation)
                    GoTo restart
                End If
            Else
                raiseError("terminating signal caught, start shutdown.")
            End If
        End If
    End Sub

    Public Sub unhandledException(ByVal ex As Exception)
        shutdown()
    End Sub

    Public Sub main(ByVal args() As String)
        startmain(AddressOf unhandledException)
        If args.Length > 0 Then
            configfile = args(0)
            raiseError("use argument0 " + configfile + " as config file, instead of default config file")
        End If

        startService()
        monitor()
        shutdown()
    End Sub

    Private Sub config_ConfigChanged() Handles config.configChanged
        restart = True
        shutdownService()
        startService()
        restart = False
    End Sub

    Private Sub config_ConfigfileDeleted() Handles config.configfileDeleted
        If configDeletedOperation(configfile) Then
            shutdown()
        End If
    End Sub
End Module
